package templateUtil;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.apache.velocity.VelocityContext;
import org.apache.velocity.app.VelocityEngine;

import com.sss.cn.New.model.WhNew;
import com.sss.cn.util.StringUtil;


/**
 * 生成mvc功能模块
 * 
 */
public class GenerateTemplate {
	
	
	private static final String classAuthor = "Wang zh"; // 作者姓名
	private static String functionName = "顾客收货地址"; // 功能描述
	private static final Class<?> modelClass = WhNew.class;// 要依赖的实体类[GenerateEntity.java生成的实体]
	
	private static VelocityEngine ve;
	private static String targetClassPath = modelClass.getResource("/").toString().replace("file:/", "");
	
	static {
		ve = new VelocityEngine();
		ve.setProperty(VelocityEngine.RESOURCE_LOADER, "file");
		ve.setProperty(VelocityEngine.FILE_RESOURCE_LOADER_PATH, targetClassPath);
		ve.setProperty(VelocityEngine.INPUT_ENCODING, "UTF-8");
		ve.setProperty(VelocityEngine.OUTPUT_ENCODING, "UTF-8");
		ve.init();
	}
	
	
	public static void main(String[] args) throws Exception {

		boolean isHas = false;

		// 通过model类获取路径信息
		// 目录生成结构：{packageName}/{moduleName}/{dao,service,action}/{className}
		String path = modelClass.getPackage().getName(); // com.javaosc.user.model
		path = path.substring(0, path.lastIndexOf(".")); // com.javaosc.user
		String packageName = path.substring(0, path.lastIndexOf("."));// com.javaosc
		String moduleName = path.substring(path.lastIndexOf(".") + 1);// user
		String className = StringUtils.uncapitalize(modelClass.getSimpleName());// role

		if (StringUtil.isEmpty(packageName) || StringUtil.isEmpty(moduleName) || StringUtil.isEmpty(className) || StringUtil.isEmpty(functionName)) {
			System.out.println("参数设置错误：包名、模块名、类名、功能名不能为空。");
			return;
		}
		System.out.println("=========== 包解析如下 ===========");
		System.out.println("path: " + path);
		System.out.println("packageName: " + packageName);
		System.out.println("moduleName: " + moduleName);
		System.out.println("className:" + className);
		System.out.println("=========== 解析完毕  ===========");

		// 获取类路径
		String classPathPack = modelClass.getPackage().toString().replace("package", "").trim() + ".";
		String classPathPackPath = classPathPack.replaceAll("\\.", "/");
		int targetIndex = targetClassPath.indexOf("/target");
		String classPath = targetClassPath.substring(0, targetIndex) + "/src/main/java/"  + classPathPackPath;


		// 定义模板变量
		Map<String, Object> param = new HashMap<String, Object>();
		param.put("packageName", StringUtils.lowerCase(packageName));
		param.put("moduleName", StringUtils.lowerCase(moduleName));
		param.put("uncapitalizeName", StringUtils.uncapitalize(className)); //首字母小写
		param.put("capitalizeName", StringUtils.capitalize(className)); //首字母大写
		param.put("author", StringUtils.isNotBlank(classAuthor) ? classAuthor : "bigaka generate");
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");// 设置格式化格式
		String nowDate = sdf.format(new Date());
		param.put("date", nowDate);// 当前时间
		param.put("functionName", functionName);

		boolean flag = false;
		
		// 生成Dao 接口
		String filePath = classPath.replace("model",param.get("uncapitalizeName")+ "/dao") + param.get("capitalizeName") + "Dao.java";
		File outFile = new File(filePath);
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = mergeToFile(param, "/template/dao.vm", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + filePath);
			} else {
				System.out.println(param.get("capitalizeName") + "Service.java 创建失败!");
			}
		}
		

		// 生成DaoImpl 接口实现类
		filePath = classPath.replace("model", param.get("uncapitalizeName")+ "/dao") + param.get("capitalizeName") + "DaoImpl.java";
		outFile = new File(filePath);
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = mergeToFile(param, "/template/daoImpl.vm", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + filePath);
			} else {
				System.out.println(param.get("capitalizeName") + "DaoImpl.java 创建失败!");
			}
		}
		
		
		// 生成 Service 接口
		filePath = classPath.replace("model", param.get("uncapitalizeName")+ "/service") + param.get("capitalizeName") + "Service.java";
//		String servicePath = filePath.replace(nowDir, newDir);
		String servicePath=filePath;
		outFile = new File(servicePath);
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = mergeToFile(param, "/template/service.vm", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + servicePath);
			} else {
				System.out.println(param.get("capitalizeName") + "Service.java 创建失败!");
			}
		}
		

		// 生成 ServiceImpl 接口实现类
		filePath = classPath.replace("model", param.get("uncapitalizeName")+ "/service") + param.get("capitalizeName") + "ServiceImpl.java";
		outFile = new File(filePath);
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = mergeToFile(param, "/template/serviceImpl.vm", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + filePath);
			} else {
				System.out.println(param.get("capitalizeName") + "ServiceImpl.java 创建失败!");
			}
		}

		// 生成 Action
		filePath = classPath.replace("model", param.get("uncapitalizeName")+ "/action") + param.get("capitalizeName") + "Action.java";
		String actionPath=filePath;
		outFile = new File(actionPath);
	
		if(outFile.exists()){
			isHas = true;
		}else{
			flag = mergeToFile(param, "/template/action.vm", outFile);
			if (flag) {
				System.out.println("生成文件的路径：" + actionPath);
			} else {
				System.out.println(param.get("capitalizeName") + "Action.java 创建失败!");
			}
		}

		if (!isHas && flag) {
			System.out.println("提示：模块创建完毕，请验证！");
		} else {
			System.out.println("提示：为防止生成覆盖，已生成的文件不做处理，若要重新生成，请删除原来的文件(注意代码备份！)");
		}

	}
	
	public static boolean mergeToFile(Map<String, Object> param, String templateLocation, File outFile) {
		if (StringUtil.isNotEmpty(templateLocation)) {
			if(!outFile.getParentFile().exists()){
				outFile.getParentFile().mkdirs();
			}
			BufferedWriter bufferedWriter = null;
			try {
				VelocityContext vc = new VelocityContext(param);
				FileWriter writer = new FileWriter(outFile, true);
				bufferedWriter = new BufferedWriter(writer);
				ve.mergeTemplate(templateLocation, "UTF-8", vc, bufferedWriter);
				bufferedWriter.flush();
				writer.close();
				return true;
			} catch (Exception e) {
				System.out.println(e.getMessage());
				return false;
			}finally{
				try {
					if(bufferedWriter!=null){
						bufferedWriter.close();
					}
				} catch (IOException e) {
					System.out.println(e.getMessage());
				}
			}
		}
		
		return false;
	}

}
